package cringer::weather;

# weather.pm
# checks yahoo!'s weather api for forecast info
# And yes, this is the Google AJAX APIs IRC bot, but if someone else offers a cool service that
# provides cool functionality, USE it! I don't work for Google! Mwhaha!

use JSON;
use XML::RSS::Parser;


sub said{
 my $self = $_[0];
 my $args = $_[1];
 my $me = $self->{nick};
 
 if($args->{body} =~ /^(f->c|c->f): ?(\d+)$/i){
  my $t = $2;
  my $r = $t . (($1 eq 'f->c') ? 'F = ' . convertFtoC($t) . 'C' : 'C = ' . convertCtoF($t) . 'F');
  return $r;
 }
 
 
 unless($args->{body} =~ /^(conditions|weather|forecast): ?(.+)$/i){
  return;
 }
 
 my $mode = lc($1);
 my $q = $2;
 if($q =~ /^woeid:(\d+)$/){ # if we have a woeid, go with it
  $q = $1;
 } else { # otherwise, we need to find a woeid
  # This url is part of Yahoo!'s lookup app. Since we don't have a list of all the WOEIDs, we use it to look them up.
  # Note: If Yahoo! doesn't like this, we'll have to submit a query to Y! Weather or something and parse the WOEID from somewhere on the page.
  my $lUrl = qq~http://weather.yahoo.com/locationWidget/widget/htdocs/locationWidget.php?appId=us_weather&location=~ . cringer::uriencode($q);
  my $r = $self->{ua}->get($lUrl);
  my $lJson;
  my $str = $r->decoded_content;
  # Because Y! expects cookie support, we get a whacky error that breaks the JSON response. So we truncate the thing.
  $str =~ s/,"html":.*/\}/;
  eval { $lJson = from_json($str); };
  if($@ ne ''){
   print qq~\n================\nWeather error:\n~ . $str . qq~\nError: $@\n================\n~;
   return qq~I'm sorry, but I encountered an error processing your query.~;
  }
  if((defined($lJson->{locations})) && (defined($lJson->{locations}->{id}))){
   $q = $lJson->{locations}->{id};
  } else {
   return qq~I'm sorry, I was unable to find a WOEID for "$q"~;
  }
 }
 
 my @r;
 XML::RSS::Parser->register_ns_prefix('yweather','http://xml.weather.yahoo.com/ns/rss/1.0'); # register the yweather ns
 XML::RSS::Parser->register_ns_prefix('geo','http://www.w3.org/2003/01/geo/wgs84_pos#'); # register the geo ns
 my $p = XML::RSS::Parser->new;
 my $wUrl = qq~http://weather.yahooapis.com/forecastrss?w=~ . cringer::uriencode($q);
 my $w = $p->parse_uri($wUrl);

 foreach my $item ($w->query('//item')){
  my $title = $item->query('title');
  my $place = $title->text_content;
  $place =~ s/.*? for (.*?) at .*/$1/i;
  if($mode ne 'conditions'){
   push(@r, ucfirst($mode) . qq~ for $place~);
  }
  my $presConditions = $item->query('yweather:condition');
  my $conditions = $presConditions->{attributes};
  if ($mode ne 'forecast'){
   push(@r, qq~Current conditions ~ . (($mode eq 'conditions') ? qq~for $place ~ : '') . qq~($conditions->{'{}date'}): $conditions->{'{}text'} ~ . formatTemp($conditions->{'{}temp'}));
  }
  if($mode ne 'conditions'){
   if($mode ne 'forecast'){
    push(@r, qq~Forecast for the next 2 days:~);
   }
   foreach my $node ($item->query('yweather:forecast')){
    my $forecast = $node->{attributes};
    push(@r, qq~$forecast->{'{}day'}: $forecast->{'{}text'}, hi:~ . formatTemp($forecast->{'{}high'}) . qq~ low:~ . formatTemp($forecast->{'{}low'}));
   }
  }
  my $link = $item->query('link');
  $link = $link->text_content;
  push(@r, qq~For more info: ~ . $link);
 }
 if(@r == 0){
  return;
 } else {
  return @r;
 }
}

sub formatTemp{
 my $f = shift;
 return $f . qq~F (~ . convertFtoC($f) . qq~C)~;
}

sub convertFtoC{
 my $f = shift;
 return sprintf("%.0f", ($f - 32) / 1.8);
}

sub convertCtoF{
 my $c = shift;
 return sprintf("%.0f", ($c * 1.8) + 32);
}


sub commandList{ # a simple help routine to return a list of the commands we'll respond to
 my @commands;
 foreach my $c (qw~weather conditions forecast~){
  push(@commands, qq~$c: [city|woeid:<WOEID>]~);
 }
}



return 1;